package apps

import (
	"gitee.com/captials-team/ubdframe/src/common"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/pkg/logs"
	"go.uber.org/dig"
	"sync"
)

type App struct {
	name    string
	servers []interfaces.ItfApiServer
	worker  []interfaces.ItfWorker

	module bool
}

func (app *App) Name() string {
	return app.name
}

func (app *App) Start() error {
	var wg sync.WaitGroup

	for index, v := range app.servers {
		wg.Add(1)
		server := v

		//对模块支持进行处理
		if s, ok := server.(interfaces.ItfSupportModule); ok && s != nil {
			//设置了module才是开启模块
			if app.module {
				s.WithModule(app.module)
			}
		}

		logs.Out.Info("====== App[%s] START[%d/%d]", app.Name(), index+1, len(app.servers))
		go func() {
			defer wg.Done()

			err := server.Start()
			if err != nil {
				logs.Out.Error("====== App[%s] START FAIL %s", app.Name(), err)
				return
			}
		}()
	}
	wg.Wait()

	return nil
}

func (app *App) Stop() error {
	var wg sync.WaitGroup

	for _, v := range app.servers {
		wg.Add(1)
		server := v
		go func() {
			defer wg.Done()
			err := server.Stop()
			common.ErrPanic(err)
		}()
	}
	wg.Wait()
	return nil
}

func (app *App) WithName(name string) *App {
	app.name = name
	return app
}

// WithModule 是否以模块处理
func (app *App) WithModule(t bool) *App {
	app.module = t
	return app
}

// WithServer 指定任意Server
func (app *App) WithServer(s interfaces.ItfApiServer) *App {
	app.servers = append(app.servers, s)
	return app
}

// WithApiServer 指定apiServer
func (app *App) WithApiServer(s interfaces.ItfApiServer) *App {
	app.servers = append(app.servers, s)
	return app
}

// WithWorker 指定worker
func (app *App) WithWorker(s interfaces.ItfWorker) *App {
	app.servers = append(app.servers, s)
	return app
}

func NewApp(di *dig.Container, name string) *App {
	return &App{
		name: name,
	}
}
